#pragma once

#ifndef VTTTILESTORE_H
#define VTTTILESTORE_H

#include "VTTObject.h"
#include "VTTDataTypes.h"

#include <array>
#include <map>
#include <set>
#include <vector>

#include <boost/thread/thread.hpp>

class VTTAtlas;

/**
  *	VTTTileStore objects represent Tile Stores that are each based on a VTTAtlas object
  */
class VTTTileStore : public VTTObject
{
public:
	VTTTileStore( const VTTAtlas &atlas );
	~VTTTileStore( void );

	//void CancelAtlasAndTileStoreGeneration( void );

	const std::vector<VTTTileInfo> &FetchUpdateResults( void ) const;

	bool GetUpdateResult( void ) const;
	bool GetWriteResult( void ) const;

	bool IsUpdating( void ) const;
	bool IsWriting( void ) const;

	void Update( void (*callbackFunction)(bool) = 0 );
	void UpdateInSeparateThread( void (*callbackFunction)(bool) = 0 );
	
	void Write( bool overwrite = true, void (*callbackFunction)(bool) = 0 );
	void WriteInSeparateThread( bool overwrite = true, void (*callbackFunction)(bool) = 0 );

	void WriteAtlasAndTileStoreInSeparateThread( bool overwrite = true, void (*callbackFunction)(bool) = 0 );

/*	static void GetGaussianFilterKernel( const UINT32 &width, const UINT32 &height, const float &sigma, float *kernel );*/

private:
	/** Pointer to the VTTAtlas object the Tile Store is based on */
	VTTAtlas *mAtlas;
	/** Full path of the Tile Store */
	std::string mFullPath;
	/** Vector, that stores the information about all tiles (coordinates and mipmap levels) that were updated during the update procedure */
	std::vector<VTTTileInfo> mUpdateResults;
	/** Boolean value indicating whether the Tile Store is currently updated or not */
	bool mIsUpdating;
	/** Boolean value indicating whether the Tile Store is currently generated or not */
	bool mIsWriting;
	/** Result of the last update procedure. True when it was successful, False otherwise */
	bool mUpdateResult;
	/** Result of the last generation procedure. True when it was successful, False otherwise */
	bool mWriteResult;
	/** Boolean value indicating whether the Atlas and the Tile Store is currently generated or not */
	bool mIsWritingAtlasAndTileStore;
	/** Number of components in a single pixel of the Tile Store */
	UINT32 mNumComponents;

	/** Thread that is used for updating the Tile Store */
	boost::thread mUpdateThread;
	/** Thread that is used for writing the Tile Store */
	boost::thread mWriteThread;
	/** Thread that is used for writing the Atlas and the Tile Store */
	boost::thread mWriteAtlasAndTileStoreThread;

	bool DoIt( bool overwrite, bool update, std::map<std::tr1::array<UINT32, 2>, std::set<std::tr1::array<UINT32, 2>>> &tilesToConsider );

	VTTAtlas *GetAtlas( void );

	void SetIsWritingAtlasAndTileStore( bool value );
	void ScaleRGBImageToTheHalf( unsigned char *dest, const unsigned char *src, UINT32 srcWidth );

	static void UpdateThread( VTTTileStore *tileStore, void (*callbackFunction)(bool) = 0 );
	static void WriteThread( VTTTileStore *tileStore, bool overwrite = true, void (*callbackFunction)(bool) = 0 );
	static void WriteAtlasAndTileStoreThread( VTTTileStore *tileStore, bool overwrite = true, void (*callbackFunction)(bool) = 0 );
};

#endif // VTTTILESTORE_H